import Clipboard from 'clipboard'

export function isNull(value) {
  return (value === null) || (value === undefined);
}

export function isNotNull(value) {
  return (value !== null) && (value !== undefined);
}

export function isEmptyStr(str) {
  //return (str === undefined) || (!str) || (!/[^\s]/.test(str));
  return (str === undefined) || (!str && (str !== 0) && (str !== '0')) || (!/[^\s]/.test(str));
}

export const generateId = function () {
  return Math.floor(Math.random() * 100000 + Math.random() * 20000 + Math.random() * 5000);
}

export const getGuid = function () {
  let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    var r = Math.random() * 16 | 0,
      v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
  return uuid.replace(/-/g, '').toUpperCase()
}

export const deepClone = function (origin) {
  if (origin === undefined) {
    return undefined
  }

  return JSON.parse(JSON.stringify(origin))
}

export const overwriteObj = function (obj1, obj2) {  /* 浅拷贝对象属性，obj2覆盖obj1 */
  // for (let prop in obj2) {
  //   if (obj2.hasOwnProperty(prop)) {
  //     obj1[prop] = obj2[prop]
  //   }
  // }

  Object.keys(obj2).forEach(prop => {
    obj1[prop] = obj2[prop]
  })
}

export const addWindowResizeHandler = function (handler) {
  let oldHandler = window.onresize
  if (typeof window.onresize != 'function') {
    window.onresize = handler
  } else {
    window.onresize = function () {
      oldHandler()
      handler()
    }
  }
}

const createStyleSheet = function () {
  let head = document.head || document.getElementsByTagName('head')[0];
  let style = document.createElement('style');
  style.type = 'text/css';
  head.appendChild(style);
  return style.sheet;
}

export const insertCustomCssToHead = function (cssCode, formId = '') {
  let head = document.getElementsByTagName('head')[0]
  let oldStyle = document.getElementById('vform-custom-css')
  if (!!oldStyle) {
    head.removeChild(oldStyle)  //先清除后插入！！
  }
  if (!!formId) {
    oldStyle = document.getElementById('vform-custom-css' + '-' + formId)
    !!oldStyle && head.removeChild(oldStyle)  //先清除后插入！！
  }

  let newStyle = document.createElement('style')
  newStyle.type = 'text/css'
  newStyle.rel = 'stylesheet'
  newStyle.id = !!formId ? 'vform-custom-css' + '-' + formId : 'vform-custom-css'
  try {
    newStyle.appendChild(document.createTextNode(cssCode))
  } catch (ex) {
    newStyle.styleSheet.cssText = cssCode
  }

  head.appendChild(newStyle)
}

export const insertGlobalFunctionsToHtml = function (functionsCode, formId = '') {
  let bodyEle = document.getElementsByTagName('body')[0]
  let oldScriptEle = document.getElementById('v_form_global_functions')
  !!oldScriptEle && bodyEle.removeChild(oldScriptEle)  //先清除后插入！！
  if (!!formId) {
    oldScriptEle = document.getElementById('v_form_global_functions' + '-' + formId)
    !!oldScriptEle && bodyEle.removeChild(oldScriptEle)  //先清除后插入！！
  }

  let newScriptEle = document.createElement('script')
  newScriptEle.id = !!formId ? 'v_form_global_functions' + '-' + formId : 'v_form_global_functions'
  newScriptEle.type = 'text/javascript'
  newScriptEle.innerHTML = functionsCode
  bodyEle.appendChild(newScriptEle)
}

export const optionExists = function (optionsObj, optionName) {
  if (!optionsObj) {
    return false
  }

  return Object.keys(optionsObj).indexOf(optionName) > -1
}

export const loadRemoteScript = function (srcPath, callback) {  /*加载远程js，加载成功后执行回调函数*/
  let sid = encodeURIComponent(srcPath)
  let oldScriptEle = document.getElementById(sid)

  if (!oldScriptEle) {
    let s = document.createElement('script')
    s.src = srcPath
    s.id = sid
    document.body.appendChild(s)

    s.onload = s.onreadystatechange = function (_, isAbort) { /* 借鉴自ace.js */
      if (isAbort || !s.readyState || s.readyState === "loaded" || s.readyState === "complete") {
        s = s.onload = s.onreadystatechange = null
        if (!isAbort) {
          callback()
        }
      }
    }
  }
}

export function traverseFieldWidgets(widgetList, handler, parent = null, tabParent) {
  if (!widgetList) {
    return
  }

  widgetList.map(w => {
    if (w.formItemFlag) {
      handler(w, parent, tabParent)
    } else if (w.type === 'grid') {
      w.cols.map(col => {
        traverseFieldWidgets(col.widgetList, handler, w, tabParent)
      })
    } else if (w.type === 'table') {
      w.rows.map(row => {
        row.cols.map(cell => {
          traverseFieldWidgets(cell.widgetList, handler, w, tabParent)
        })
      })
    } else if (w.type === 'tab') {
      w.tabs.map(tab => {traverseFieldWidgets(tab.widgetList, handler, w, tab)})
    } else if (w.type === 'layout-left-right') {
      traverseFieldWidgets(w.leftLists.widgetList, handler, w, tabParent)
      traverseFieldWidgets(w.rightLists.widgetList, handler, w, tabParent)
    } else if (w.type === 'layout-sync') {
      traverseFieldWidgets(w.leftLists.widgetList, handler, w, tabParent)
      traverseFieldWidgets(w.rightLists.widgetList, handler, w, tabParent)
    } else if (w.type === 'layout-full') { // TODO 完整布局数据处理
      traverseFieldWidgets(w.widgetList.asideList, handler, w, tabParent)
      traverseFieldWidgets(w.widgetList.headerLeftList, handler, w, tabParent)
      traverseFieldWidgets(w.widgetList.headerRightList, handler, w, tabParent)
      traverseFieldWidgets(w.widgetList.conditionLeftList, handler, w, tabParent)
      traverseFieldWidgets(w.widgetList.conditionRightList, handler, w, tabParent)
      traverseFieldWidgets(w.widgetList.downConditionLeftList, handler, w, tabParent)
      traverseFieldWidgets(w.widgetList.downConditionRightList, handler, w, tabParent)
      traverseFieldWidgets(w.widgetList.mainUpList, handler, w, tabParent)
      traverseFieldWidgets(w.widgetList.mainDownList, handler, w, tabParent)
      traverseFieldWidgets(w.widgetList.footerList, handler, w, tabParent)
    } else if (w.type === 'sub-form') {
      traverseFieldWidgets(w.widgetList, handler, w, tabParent)
    } else if (w.category === 'container') {  //自定义容器
      traverseFieldWidgets(w.widgetList, handler, w, tabParent)
    }
  })
}

export function traverseContainerWidgets(widgetList, handler) {
  if (!widgetList) {
    return
  }

  widgetList.map(w => {
    if (w.category === 'container') {
      handler(w)
    }

    if (w.type === 'grid') {
      w.cols.map(col => {
        traverseContainerWidgets(col.widgetList, handler)
      })
    } else if (w.type === 'table') {
      w.rows.map(row => {
        row.cols.map(cell => {
          traverseContainerWidgets(cell.widgetList, handler)
        })
      })
    } else if (w.type === 'tab') {
      w.tabs.map(tab => {
        traverseContainerWidgets(tab.widgetList, handler)
      })
    } else if (w.type === 'layout-left-right') {
      traverseContainerWidgets(w.leftLists.widgetList, handler)
      traverseContainerWidgets(w.rightLists.widgetList, handler)
    } else if (w.type === 'layout-sync') {
      traverseContainerWidgets(w.leftLists.widgetList, handler)
      traverseContainerWidgets(w.rightLists.widgetList, handler)
    }
    else if (w.type === 'layout-full') { // TODO 完整布局数据处理
      traverseFieldWidgets(w.widgetList.asideList, handler)
      traverseFieldWidgets(w.widgetList.headerLeftList, handler)
      traverseFieldWidgets(w.widgetList.headerRightList, handler)
      traverseFieldWidgets(w.widgetList.conditionLeftList, handler)
      traverseFieldWidgets(w.widgetList.conditionRightList, handler)
      traverseFieldWidgets(w.widgetList.downConditionLeftList, handler)
      traverseFieldWidgets(w.widgetList.downConditionRightList, handler)
      traverseFieldWidgets(w.widgetList.mainUpList, handler)
      traverseFieldWidgets(w.widgetList.mainDownList, handler)
      traverseFieldWidgets(w.widgetList.footerList, handler)
    } else if (w.type === 'sub-form') {
      traverseContainerWidgets(w.widgetList, handler)
    } else if (w.category === 'container') {  //自定义容器
      traverseContainerWidgets(w.widgetList, handler)
    }
  })
}

export function traverseAllWidgets(widgetList, handler) {
  if (!widgetList) {
    return
  }

  widgetList.map(w => {
    handler(w)

    if (w.type === 'grid') {
      w.cols.map(col => {
        handler(col)
        traverseAllWidgets(col.widgetList, handler)
      })
    } else if (w.type === 'table') {
      w.rows.map(row => {
        row.cols.map(cell => {
          handler(cell)
          traverseAllWidgets(cell.widgetList, handler)
        })
      })
    } else if (w.type === 'tab') {
      w.tabs.map(tab => {
        traverseAllWidgets(tab.widgetList, handler)
      })
    } else if (w.type === 'layout-left-right') {
      traverseAllWidgets(w.leftLists.widgetList, handler)
      traverseAllWidgets(w.rightLists.widgetList, handler)
    } else if (w.type === 'layout-sync') {
      traverseAllWidgets(w.leftLists.widgetList, handler)
      traverseAllWidgets(w.rightLists.widgetList, handler)
    }
    // TODO 完整布局数据处理
    else if (w.type === 'layout-full') {
      traverseFieldWidgets(w.widgetList.asideList, handler)
      traverseFieldWidgets(w.widgetList.headerLeftList, handler)
      traverseFieldWidgets(w.widgetList.headerRightList, handler)
      traverseFieldWidgets(w.widgetList.conditionLeftList, handler)
      traverseFieldWidgets(w.widgetList.conditionRightList, handler)
      traverseFieldWidgets(w.widgetList.downConditionLeftList, handler)
      traverseFieldWidgets(w.widgetList.downConditionRightList, handler)
      traverseFieldWidgets(w.widgetList.mainUpList, handler)
      traverseFieldWidgets(w.widgetList.mainDownList, handler)
      traverseFieldWidgets(w.widgetList.footerList, handler)
    } 
    else if (w.type === 'sub-form') {
      traverseAllWidgets(w.widgetList, handler)
    } else if (w.category === 'container') {  //自定义容器
      traverseAllWidgets(w.widgetList, handler)
    }
  })
}

function handleWidgetForTraverse(widget, handler) {
  if (!!widget.category) {
    traverseFieldWidgetsOfContainer(widget, handler)
  } else if (widget.formItemFlag) {
    handler(widget)
  }
}

/**
 * 遍历容器内的字段组件
 * @param con
 * @param handler
 */
export function traverseFieldWidgetsOfContainer(con, handler) {
  if (con.type === 'grid') {
    con.cols.forEach(col => {
      col.widgetList.forEach(cw => {
        handleWidgetForTraverse(cw, handler)
      })
    })
  } else if (con.type === 'table') {
    con.rows.forEach(row => {
      row.cols.forEach(cell => {
        cell.widgetList.forEach(cw => {
          handleWidgetForTraverse(cw, handler)
        })
      })
    })
  } else if (con.type === 'tab') {
    con.tabs.forEach(tab => {
      tab.widgetList.forEach(cw => {
        handleWidgetForTraverse(cw, handler)
      })
    })
  } else if (con.type === 'layout-left-right') {
    if (con.leftLists.length) {
      con.leftLists.widgetList.forEach(cw => {
        handleWidgetForTraverse(cw, handler)
      })
    }
    if (con.rightLists.length) {
      con.rightLists.widgetList.forEach(cw => {
        handleWidgetForTraverse(cw, handler)
      })
    }
  } else if (con.type === 'layout-sync') {
    if (con.leftLists.length) {
      con.leftLists.widgetList.forEach(cw => {
        handleWidgetForTraverse(cw, handler)
      })
    }
    if (con.rightLists.length) {
      con.rightLists.widgetList.forEach(cw => {
        handleWidgetForTraverse(cw, handler)
      })
    }
  }
  else if (con.type === 'layout-full') { // TODO 完整布局数据处理
    con.widgetList.asideList.forEach(cw => { handleWidgetForTraverse(cw, handler) })
    con.widgetList.headerLeftList.forEach(cw => { handleWidgetForTraverse(cw, handler) })
    con.widgetList.headerRightList.forEach(cw => { handleWidgetForTraverse(cw, handler) })
    con.widgetList.conditionLeftList.forEach(cw => { handleWidgetForTraverse(cw, handler) })
    con.widgetList.conditionRightList.forEach(cw => { handleWidgetForTraverse(cw, handler) })
    con.widgetList.downConditionLeftList.forEach(cw => { handleWidgetForTraverse(cw, handler) })
    con.widgetList.downConditionRightList.forEach(cw => { handleWidgetForTraverse(cw, handler) })
    con.widgetList.mainUpList.forEach(cw => { handleWidgetForTraverse(cw, handler) })
    con.widgetList.mainDownList.forEach(cw => { handleWidgetForTraverse(cw, handler) })
    con.widgetList.footerList.forEach(cw => { handleWidgetForTraverse(cw, handler) })
  }
  else if (con.type === 'sub-form') {
    con.widgetList.forEach(cw => {
      handleWidgetForTraverse(cw, handler)
    })
  } else if (con.category === 'container') {  //自定义容器
    con.widgetList.forEach(cw => {
      handleWidgetForTraverse(cw, handler)
    })
  }
}

/**
 * 获取所有字段组件
 * @param widgetList
 * @returns {[]}
 */
export function getAllFieldWidgets(widgetList) {
  if (!widgetList) {
    return []
  }

  let result = []
  let handlerFn = (w, parent, tabParent) => {
    const fieldObj = {
      id: w.id,
      key: w.key,
      type: w.type,
      name: w.options.name,
      label: w.options.label,
      field: JSON.parse(JSON.stringify(w)),
      dataField: w.options.dataField,
    }
    if (tabParent) {
      fieldObj['tabInfo'] = {
        id: tabParent.id,
        name: tabParent.options.name,
        label: tabParent.options.label
      }
    }
    result.push(fieldObj)
  }
  traverseFieldWidgets(widgetList, handlerFn)

  return result
}

/**
 * 获取所有容器组件
 * @param widgetList
 * @returns {[]}
 */
export function getAllContainerWidgets(widgetList) {
  if (!widgetList) {
    return []
  }

  let result = []
  let handlerFn = (w) => {
    result.push({
      type: w.type,
      name: w.options.name,
      container: w
    })
  }
  traverseContainerWidgets(widgetList, handlerFn)

  return result
}

export function copyToClipboard(content, clickEvent, $message, successMsg, errorMsg) {
  const clipboard = new Clipboard(clickEvent.target, {
    text: () => content
  })

  clipboard.on('success', () => {
    $message.success(successMsg)
    clipboard.destroy()
  })

  clipboard.on('error', () => {
    $message.error(errorMsg)
    clipboard.destroy()
  })

  clipboard.onClick(clickEvent)
}

export function getQueryParam(variable) {
  let query = window.location.search.substring(1);
  let vars = query.split("&")
  for (let i = 0; i < vars.length; i++) {
    let pair = vars[i].split("=")
    if (pair[0] == variable) {
      return pair[1]
    }
  }

  return undefined;
}

export function getDefaultFormConfig() {
  return {
    modelName: 'formData',
    refName: 'vForm',
    rulesName: 'rules',
    labelWidth: 80,
    labelPosition: 'left',
    size: '',
    labelAlign: 'label-left-align',
    cssCode: '',
    customClass: [],
    functions: '',  //全局函数
    layoutType: 'PC',
    jsonVersion: 3,

    onFormCreated: '',
    onFormMounted: '',
    onFormDataChange: '',
  }
}

export function buildDefaultFormJson() {
  return {
    widgetList: [],
    formConfig: deepClone(getDefaultFormConfig())
  }
}

export const getFieldFormModelData = function (widgetList) {
  if (!(!!widgetList && (widgetList.length > 0))) return
  widgetList.forEach(wItem => {
    traverseFieldFormModel(wItem, formModel)
  })
}
const traverseFieldFormModel = function (wItem, formModel = {}) {
  // 如果是容器
  if (wItem.category === 'container') {
    const { widgetList, tabs, rows, cols } = wItem
    switch (wItem.type) {
      case 'tab':
        if (!!tabs && (tabs.length > 0)) {
          tabs.forEach(tabItem => {
            traverseFieldFormModel(tabItem, formModel)
          })
        }
        break;
      case 'table':
        if (!!rows && (rows.length > 0)) {
          rows.forEach(rowItem => {
            const { cols } = rowItem
            cols.forEach(childItem => {
              traverseFieldFormModel(childItem, formModel)
            })
          })
        }
        break;
      case 'grid':
        if (!!cols && (cols.length > 0)) {
          cols.forEach(childItem => {
            traverseFieldFormModel(childItem, formModel)
          })
        }
        break;
      case 'sub-form':
        const { name: subFormName, showBlankRow } = wItem.options.name
        let subFormDataRow = {}
        if (showBlankRow) {
          if (!!widgetList && widgetList.length > 0) {
            widgetList.forEach(subFormItem => {
              if (!!subFormItem.formItemFlag) {
                subFormDataRow[subFormItem.options.name] = subFormItem.options.defaultValue
              }
            })
            formModel[subFormName] = [subFormDataRow]
          } else {
            formModel[subFormName] = []
          }
        }
        break;
      case 'grid-col':
        if (!!widgetList && (widgetList.length > 0)) {
          widgetList.forEach(childItem => {
            traverseFieldFormModel(childItem, formModel)
          })
        }
        break;
      case 'table-cell':
        if (!!widgetList && (widgetList.length > 0)) {
          widgetList.forEach(childItem => {
            traverseFieldFormModel(childItem, formModel)
          })
        }
        break;
      default:
        if (!!widgetList && (widgetList.length > 0)) {
          widgetList.forEach(childItem => {
            traverseFieldFormModel(childItem, formModel)
          })
        }
        break;
    }
  }
  if (!!wItem.formItemFlag) {
    formModel[wItem.options.name] = wItem.options.defaultValue
  }
}